﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Fiddler;
using System.Windows.Forms;
using System.Drawing;
using FiddlerExUtils.Helper;
using FiddlerExUtils.Tools;

namespace FiddlerInspectorsEx
{
    public class ResquestDecrypt : Inspector2, IRequestInspector2
    {
        JSONView jsonView;
        private Session oSession;
        private HTTPRequestHeaders m_headers;
        private bool isJson = false;
        private string reqBody = "";

        private byte[] m_entityBody;
        public bool m_bDirty;
        private static Dictionary<string, object> dic = new Dictionary<string, object>();
        public bool bReadOnly { get; set; }

        public void Clear()
        {
            m_entityBody = null;
            m_bDirty = false;
        }

        public ResquestDecrypt()
        {
            jsonView = new JSONView(this as IRequestInspector2);
            //注册监听事件
            PictureBox PB_Save = (PictureBox)jsonView.rtbox_Json.Controls["PB_Save"];
            PB_Save.Click += PB_Save_Click;
        }

        private void PB_Save_Click(object sender, EventArgs e)
        {
            bool isChange = CommitAnyChanges(oSession);
            if (isChange)
            {
                FiddlerApplication.UI.ResumeBreakpointedSession(oSession);
                AssignSession(oSession);
            }
        }

        public HTTPRequestHeaders headers
        {
            get
            {
                return m_headers;    // Return null if your control doesn't allow header editing.
            }
            set
            {
                if (value == null)
                {
                    this.Clear();
                }
                else
                {
                    m_headers = value;

                    JSONView.headers = value;
                    //jsonView.TXT_HeadLine.Text = m_headers.HTTPMethod + "   " + m_headers["S-Name"] + "   " + m_headers.RequestPath + "   " + m_headers["Content-Length"] + "   " + m_headers.HTTPVersion;
                }
            }
        }

        public byte[] body
        {
            get
            {
                return m_entityBody;
            }
            set
            {    // Here's where the action is.  It's time to update the visible display of the text
                m_entityBody = value;

                if (null != m_entityBody)
                {
                    reqBody = "";
                    try
                    {
                        reqBody = System.Text.Encoding.UTF8.GetString(m_entityBody);
                    }
                    catch (Exception e)
                    {
                        FiddlerApplication.Log.LogString("Request: " + e.StackTrace);
                    }

                    JSONView.reqBody = reqBody;
                    jsonView.rtbox_Json.Clear();
                    jsonView.tvJSON.Nodes.Clear();
                    dic.Clear();
                    dic.Add("interfaceName", "");
                    dic.Add("urlPath", m_headers.RequestPath);
                    dic.Add("type", 0);
                    jsonView.tvJSON.Tag = dic;
                    CommonFunction.SetJSON(jsonView.tvJSON, reqBody);
                    isJson = CommonFunction.IsJson(reqBody);
                    jsonView.isJson = isJson;
                    if (isJson)
                    {
                        jsonView.webBrowser1.ScriptErrorsSuppressed = true;
                        jsonView.webBrowser1.DocumentText = CommonFunction.GetDocumentTextWithJson(reqBody.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("\\", "\\\\").Replace("\"", "\\\""), false);
                        
                    }
                    jsonView.rtbox_Json.SetText(CommonFunction.ConvertJsonString(reqBody, false), false);
                    // TODO: Use correct encoding based on content header.
                }
                else
                {
                    jsonView.TXT_HeadLine.Clear();
                    jsonView.rtbox_Json.Clear();
                    jsonView.tvJSON.Nodes.Clear();
                    jsonView.webBrowser1.DocumentText = "";
                }
                m_bDirty = !bReadOnly;   // Note: Be sure to have an OnTextChanged handler for the textbox which sets m_bDirty to true!
            }
        }

        public bool bDirty
        {
            get
            {
                return m_bDirty;
            }
            set
            {

            }
        }

        public override int GetOrder()
        {
            return 0;
        }

        public override void AddToTab(System.Windows.Forms.TabPage o)
        {
            // Essentially the TextView class is simply a usercontrol containing a textbox.
            o.Text = "RequestView";
            o.Controls.Add(jsonView);
            o.Controls[0].Dock = DockStyle.Fill;
        }

        public override void AssignSession(Session oS)
        {
            oSession = oS;
            jsonView.TXT_HeadLine.Text = oSession.fullUrl;
            IRequestInspector2 inspector = this as IRequestInspector2;
            if (inspector != null)
            {
                inspector.headers = oS.oRequest.headers;
                inspector.bReadOnly = (oS.state != SessionStates.HandTamperRequest) && !oS.oFlags.ContainsKey("x-Unlocked");
                inspector.body = oS.requestBodyBytes;

                if(oS.state == SessionStates.Done)
                {
                    jsonView.oSession = oS;
                }
                
                jsonView.rtbox_Json.Tag = m_headers;
                jsonView.rtbox_Json.SetReadOnly(bReadOnly);
                jsonView.Btn_JSONZhuanYi.Enabled = bReadOnly;
                //MessageBox.Show(jsonView.tvJSON.Visible+"");
                if (!bReadOnly || !isJson) //断点编辑
                {
                    jsonView.rtbox_Json.SetText(reqBody);
                    jsonView.rtbox_Json.Visible = true;
                    jsonView.isShowTextBox = true;
                    jsonView.webBrowser1.Visible = false;
                    jsonView.tvJSON.Visible = false;
                    jsonView.textShowBtn.Enabled = false;
                    //jsonView.Btn_JSONZhuanYi.Enabled = true;
                }
                else if (bReadOnly && !jsonView.Btn_JSONZhuanYi.Enabled) //转义界面
                {
                    string jsonStr = reqBody.Replace("\"", "\\" + "\"");
                    jsonView.rtbox_Json.SetText(jsonStr, false);
                    jsonView.rtbox_Json.Visible = true;
                    jsonView.webBrowser1.Visible = false;
                }
                else //webbrowser
                {
                    jsonView.rtbox_Json.Visible = false;
                    jsonView.isShowTextBox = false;
                    jsonView.tvJSON.Visible = false;
                    jsonView.webBrowser1.Visible = true;
                    jsonView.textShowBtn.Enabled = false;
                }
            }

            //Mock颜色标记
            if (bReadOnly && oS.oFlags.ContainsKey("request-replace"))
            {
                jsonView.TXT_HeadLine.AppendText("   Mock: " + oS.oFlags["request-replace"]);
                jsonView.TXT_HeadLine.ForeColor = ColorTranslator.FromHtml(FiddlerApplication.Prefs.GetStringPref("fiddlerex.session.mockcolor", "Blue"));
                jsonView.webBrowser1.DocumentText = CommonFunction.GetDocumentTextWithJson(reqBody.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace("\\", "\\\\").Replace("\"", "\\\""), true);
            }
            else
            {
                jsonView.TXT_HeadLine.ForeColor = System.Drawing.Color.Black;
            }

            jsonView.rtbox_Json.SetBackColor(SystemColors.Window);
            if (bReadOnly)
            {
                jsonView.rtbox_Json.SetBackColor(SystemColors.Control);
            }
            jsonView.tvJSON.BackColor = System.Drawing.Color.AliceBlue;
        }

        public override bool CommitAnyChanges(Session oS)
        {
            bool flag = false;
            IRequestInspector2 inspector = this as IRequestInspector2;
            if (inspector != null)
            {
                if (!inspector.bDirty)
                {
                    return false;
                }
                if (((oS.state != SessionStates.HandTamperRequest) && !oS.oFlags.ContainsKey("x-Unlocked")) && (((inspector as Inspector2).GetFlags() & InspectorFlags.AlwaysCommitEdits) == InspectorFlags.None))
                {
                    return false;
                }
                if (inspector.headers != null)
                {
                    flag = true;
                    oS.oRequest.headers = inspector.headers;
                }
                if (inspector.body != null)
                {
                    flag = true;
                    oS.requestBodyBytes = Encoding.UTF8.GetBytes(jsonView.rtbox_Json.GetText().Trim());
                    oS.oRequest.headers["Content-Length"] = oS.requestBodyBytes.Length.ToString();
                }
                this.UnsetDirtyFlag();
                return flag;
            }
            IResponseInspector2 inspector2 = this as IResponseInspector2;
            if (inspector2 == null)
            {
                return false;
            }
            if (!inspector2.bDirty)
            {
                return false;
            }
            if (((oS.state != SessionStates.HandTamperResponse) && !oS.oFlags.ContainsKey("x-Unlocked")) && (((inspector2 as Inspector2).GetFlags() & InspectorFlags.AlwaysCommitEdits) == InspectorFlags.None))
            {
                return false;
            }
            if (inspector2.headers != null)
            {
                flag = true;
                oS.oResponse.headers = inspector2.headers;
            }
            if (inspector2.body != null)
            {
                flag = true;
                oS.responseBodyBytes = Encoding.UTF8.GetBytes(jsonView.rtbox_Json.GetText().Trim());
                oS.oResponse.headers["Content-Length"] = oS.responseBodyBytes.Length.ToString();
            }
            this.UnsetDirtyFlag();
            return flag;
        }

    }
}
